#include <webx/route.h>
#include <dbentity/T_XG_MENU.h>
#include <dbentity/T_XG_GROUP.h>

class EditMenu : public webx::ProcessBase
{
protected:
	int process();
};

HTTP_WEBAPP(EditMenu)

int EditMenu::process()
{
	param_string(id);
	param_string(url);
	param_string(flag);
	param_string(icon);
	param_string(title);
	param_string(folder);
	param_string(remark);
	param_string(enabled);
	param_string(grouplist);

	webx::CheckAlnumString(id, 0);

	checkLogin();

	string sqlcmd;
	CT_XG_MENU tab;
	int res = XG_PARAMERR;
	sp<DBConnect> dbconn = webx::GetDBConnect();
	
	tab.init(dbconn);
	tab.id = id;

	auto remove = [](CT_XG_MENU& tab){
		set<string> idset;
		CT_XG_GROUP grptab;
		map<string, string> upmap;
		map<string, string> grpmap;

		if (tab.title.val().empty())
		{
			string sqlcmd = "FOLDER=? AND ENABLED>1";

			CHECK_FALSE_RETURN(tab.findWhere(sqlcmd, tab.folder.val()));

			while (tab.next()) idset.insert(tab.id.val());

			sqlcmd = "DELETE FROM T_XG_ACCESS WHERE MENUID=?";

			if (tab.getHandle()->execute(sqlcmd) < 0) return false;
		}
		else
		{
			idset.insert(tab.id.val());
		}

		grptab.init(tab.getHandle());
		grptab.find("1=1");

		while (grptab.next())
		{
			grpmap[grptab.id.val()] = grptab.menulist.toString();
		}

		for (const string& id : idset)
		{
			string menulist;
			const string& tag = "," + id + ",";

			for (auto& item : grpmap)
			{
				string& old = item.second;

				menulist = "," + old + ",";
				menulist = stdx::replace(menulist, tag, ",");
				menulist = menulist.substr(1, menulist.length() - 2);

				if (old == menulist) continue;

				upmap[item.first] = old = menulist;
			}

			grptab.clear();
			grptab.statetime.update();

			for (auto& item : upmap)
			{
				grptab.id = item.first;
				grptab.menulist = item.second;

				if (grptab.update() < 0) return false;
			}

			tab.id = id;

			if (tab.remove() < 0) return false;
		}

		return true;
	};

	auto removeCommit = [&](CT_XG_MENU& tab){
		tab.begin();

		if (remove(tab))
		{
			tab.commit();

			return XG_OK;
		}
		else
		{
			tab.rollback();

			return XG_SYSERR;
		}
	};

	if (flag == "A" || flag == "C" || flag == "R")
	{
		webx::CheckFileName(title, 0);
		webx::CheckFileName(folder, 0);

		if (icon.empty())
		{
			if (flag == "C")
			{
				icon = "/res/img/menu/folder.png";
			}
			else
			{
				icon = "/res/img/menu/menu.png";
			}
		}
		
		if (flag == "R")
		{
			res = XG_NOTFOUND;

			sqlcmd = "FOLDER=? AND (TITLE IS NULL OR TITLE='') AND ENABLED>1";
			
			if (tab.findWhere(sqlcmd, folder) && tab.next()) res = removeCommit(tab);
		}
		else
		{
			tab.url = url;
			tab.icon = icon;
			tab.title = title;
			tab.folder = folder;
			tab.remark = remark;
			tab.enabled = enabled;
			tab.statetime.update();

			for (int i = 0; i < 5; i++)
			{
				tab.id = DateTime::GetBizId();
				tab.position = (int)(time(NULL));

				if ((res = tab.insert()) >= 0) break;
			}

			if (res > 0)
			{
				json["icon"] = tab.icon.val();
				json["id"] = tab.id.val();
			}
		}
	}
	else if (flag == "D")
	{
		res = XG_NOTFOUND;

		if (id.empty()) return simpleResponse(XG_PARAMERR);

		if (tab.find() && tab.next() && tab.enabled.val() > 1) res = removeCommit(tab);
	}
	else if (flag == "U")
	{
		res = XG_NOTFOUND;

		if (id.empty()) return simpleResponse(XG_PARAMERR);

		if (tab.find() && tab.next() && tab.enabled.val() > 1)
		{
			tab.statetime.update();
			
			if (url.length() > 0) tab.url = url;
			if (icon.length() > 0) tab.icon = icon;
			if (title.length() > 0) tab.title = title;
			if (folder.length() > 0) tab.folder = folder;
			if (remark.length() > 0) tab.remark = remark;
			if (enabled.length() > 0) tab.enabled = enabled;

			json["icon"] = tab.icon.val();

			if ((res = tab.update()) > 0)
			{
				string menulist;
				CT_XG_GROUP tab;
				map<string, string> upmap;
				const string& tag = "," + id + ",";

				tab.init(dbconn);
				
				for (JsonElement item : JsonElement(grouplist))
				{
					tab.id = item["id"].asString();
					
					if (tab.find() && tab.next())
					{
						string old = tab.menulist.toString();

						menulist = "," + old + ",";
				
						if (item["checked"].asBool())
						{
							if (menulist.find(tag) == string::npos)
							{
								menulist += id + ",";
							}
						}
						else
						{
							menulist = stdx::replace(menulist, tag, ",");
						}
						
						menulist = stdx::trim(menulist, ",");

						if (old == menulist) continue;

						upmap[tab.id.val()] = menulist;
					}
				}

				tab.clear();
				tab.statetime.update();
				
				for (auto& item : upmap)
				{
					tab.id = item.first;
					tab.menulist = item.second;

					if (tab.update() < 0) return simpleResponse(XG_SYSERR);
				}
			}
		}
	}
	else if (flag == "M")
	{
		int position = 0;
		vector<string> vec = stdx::split(folder, ",");

		if (vec.empty()) return simpleResponse(XG_PARAMERR);

		dbconn->begin();

		if (vec.size() > 1)
		{
			const char* sql = "UPDATE T_XG_MENU SET POSITION=? WHERE FOLDER=? AND (TITLE IS NULL OR TITLE='')";

			for (string& folder : vec)
			{
				dbconn->execute(sql, ++position, folder);
			}
		}
		else
		{
			vec = stdx::split(title, ",");

			const char* sql = "UPDATE T_XG_MENU SET POSITION=? WHERE FOLDER=? AND TITLE=?";

			for (string& title : vec)
			{
				dbconn->execute(sql, ++position, folder, title);
			}
		}

		dbconn->commit();

		res = vec.size();
	}
	else
	{
		res = XG_PARAMERR;
	}

	if (res >= 0)
	{
		sp<Session> session = webx::GetLocaleSession("ACCESS");

		Process::SetObject("HTTP_GROUP_SET", NULL);
		Process::SetObject("HTTP_MENU_SET", NULL);

		if (session) session->disable();
	}

	json["code"] = res;
	out << json;
	
	return XG_OK;
}